/**
 * 
 */
package kr.co.insoft.driver.amazon.impl;

import java.util.ArrayList;
import java.util.Collection;

import kr.co.insoft.driver.amazon.AmazonDriver;
import kr.co.insoft.driver.amazon.model.AmazonInstanceResultModel;
import kr.co.insoft.driver.exception.DriverException;
import kr.co.insoft.driver.exception.ExceptionCode;
import kr.co.insoft.driver.exception.NotSupportedException;
import kr.co.insoft.driver.model.InstanceModel;
import kr.co.insoft.driver.model.InstanceResultModel;

import org.springframework.util.Assert;

import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.model.CreateTagsRequest;
import com.amazonaws.services.ec2.model.InstanceType;
import com.amazonaws.services.ec2.model.Placement;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.Tag;

/**
 * Amazon 대응 드라이버
 * 
 * @author IN-SOFT Inc. GoodwillDD(sylee@in-soft.co.kr)
 * 
 */
public class AmazonDriverImpl extends AmazonDriver {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5572171386635589085L;

	public AmazonDriverImpl() {

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see kr.co.insoft.drivers.AmazonProcess#createAmazonInstance()
	 */
	public InstanceResultModel createAmazonInstance(InstanceModel instance)
			throws DriverException, NotSupportedException {
		try {
			Assert.isTrue(instance.getLaunchCount() > 0);
			Assert.isTrue(instance.getLaunchCount() <= 20);
			Assert.notNull(instance.getImageId());
			Assert.notNull(instance.getInstanceType());
			Assert.notNull(instance.getSecurityGroups());
			Assert.notNull(instance.getKeyName());
			Assert.notNull(instance.getZone());
			Assert.notNull(instance.getInstanceName());
		} catch (IllegalArgumentException e) {
			if (logger.isDebugEnabled())
				logger.debug("##### Argument Exception using instance : {}",
						instance);
			throw new DriverException(ExceptionCode.ARGUMENT_ERROR, e);
		}
		AmazonEC2 client = null;
		try {
			client = getConnection();

			RunInstancesRequest runInstancesRequest = new RunInstancesRequest();
			runInstancesRequest.setImageId(instance.getImageId());
			runInstancesRequest.setInstanceType(InstanceType.valueOf(instance
					.getInstanceType()));
			runInstancesRequest.setMinCount(1); // Min : 1
			runInstancesRequest.setMaxCount(instance.getLaunchCount()); // Max : 20
			/* 없는 경우 생성하여야 함 */
			runInstancesRequest.setSecurityGroups(instance.getSecurityGroups());
			/* 없는 경우 생성하여야 함 */
			runInstancesRequest.setKeyName(instance.getKeyName());
			runInstancesRequest.setPlacement(new Placement(instance.getZone()));
			return new AmazonInstanceResultModel(client.runInstances(
					runInstancesRequest).getReservation(), instance);
		} catch (Exception e) {
			if (logger.isDebugEnabled()) {
				logger.debug("##### using amazon ec2 client : {}", client);
				logger.debug("##### using instance : {}", instance);
			}
			throw new DriverException(ExceptionCode.DRIVER_ERROR, e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see kr.co.insoft.drivers.AmazonProcess#renameAmazonInstance()
	 */
	public void renameAmazonInstance(InstanceResultModel instanceResultModel, String instanceName)
			throws DriverException, NotSupportedException {
		try {
			Assert.notNull(amazonCredential.getEndpoint());
			Assert.notNull(instanceResultModel);
		} catch (IllegalArgumentException e) {
			if (logger.isDebugEnabled())
				logger.debug("instance : {}", instanceResultModel);
			throw new DriverException(ExceptionCode.ARGUMENT_ERROR, e);
		}
		try {
			int count = 1;
			Tag nameTag = new Tag("Name", instanceName);
			for (InstanceModel instance : instanceResultModel.getInstances()) {
				if (instanceResultModel.getInstances().size() > 1) {
					nameTag = new Tag("Name", instanceName + "-"
							+ count);
				}

				Collection<Tag> tags = new ArrayList<Tag>();
				tags.add(nameTag);

				Collection<String> resources = new ArrayList<String>();
				resources.add(instance.getInstanceId());

				CreateTagsRequest createTagsRequest = new CreateTagsRequest();
				createTagsRequest.setRequestCredentials(amazonCredential
						.getAmazonCredentials());
				createTagsRequest.setTags(tags);
				createTagsRequest.setResources(resources);

				getConnection(amazonCredential.getEndpoint()).createTags(
						createTagsRequest);
				count++;
			}
		} catch (Exception e) {
			throw new DriverException(ExceptionCode.DRIVER_ERROR, e);
		}
	}
}
